using System;
using System.IO;
using System.Text;

namespace Super
{
	public static class TextUtil
	{
		/// <summary>
		/// 根据Excel文件信息生成类文件和SO脚本文件
		/// Assets/FrameWork/Configuration/CustomExcelDataClass查看模板
		/// </summary>
		/// <param name="info"></param>
		/// <returns></returns>
		public static string GetExcelClassText(ExcelTableInfo info)
		{
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"using System;");
			SB.AppendLine(@"using System.Collections;");
			SB.AppendLine(@"using System.Collections.Generic;");
			SB.AppendLine(@"using UnityEngine;");
			SB.AppendLine(@"using UnityEditor;");
			SB.AppendLine();
			SB.AppendLine(@"namespace Super");
			SB.AppendLine(@"{");
			SB.AppendLine(@"	[Serializable]");
			SB.AppendLine($"	public class {info.nodeName} : ExcelTableNodeBase");
			SB.AppendLine(@"    {");
			for (int i = 0; i < info.fieldNames.Length; i++)
			{
				SB.AppendLine($"        public {info.fieldTypes[i]} {info.fieldNames[i]};		//{info.remarks[i]}");
			}
			SB.AppendLine(@"        public override void SetValue(string[] rowData)");
			SB.AppendLine("		{");
			SB.AppendLine("			base.SetValue(rowData);");
			SB.AppendLine();
			for (int i = 0; i < info.fieldNames.Length; i++)
			{
				Type fieldType = Type.GetType(info.fieldTypes[i]);
				if (fieldType != null && fieldType.IsEnum)
				{
					SB.AppendLine($"            {info.fieldNames[i]} = ({info.fieldTypes[i]})System.Enum.Parse(typeof({info.fieldTypes[i]}), rowData[{i}], true);");
				}
				else
				{
					SB.AppendLine($"            {info.fieldNames[i]} = ({info.fieldTypes[i]})Convert.ChangeType(rowData[{i}], typeof({info.fieldTypes[i]}));");
				}

			}
			SB.AppendLine("        }");

			SB.AppendLine(@"        public override void ValueBackFill()");
			SB.AppendLine(@"        {");
			SB.AppendLine(@"			base.ValueBackFill();");
			SB.AppendLine();
			for (int i = 0; i < info.fieldNames.Length; i++)
			{
				SB.AppendLine($"			rowData[{i}] =  {info.fieldNames[i]}.ToString();");
			}
			SB.AppendLine("        }");

			SB.AppendLine("    }");



			SB.AppendLine();
			SB.AppendLine();
			SB.AppendLine(@"	[Serializable]");
			SB.AppendLine($"	public class {info.tableName} : ExcelTableBase");
			SB.AppendLine(@"	{");
			SB.AppendLine($"        public List<" + info.nodeName + "> data = new List<" + info.nodeName + ">();");

			if (info.keys.Count > 0)
			{
				SB.Append(@"		public ExcelDictionary<");
				for (int i = 0; i < info.keys.Count; i++) SB.Append(info.keyTypes[i] + ", ");
				SB.Append($"{info.nodeName}> excelDictionary");
				SB.Append(@" = new ExcelDictionary<");
				for (int i = 0; i < info.keys.Count; i++) SB.Append(info.keyTypes[i] + ", ");
				SB.Append($"{info.nodeName}>();\n");
			}
			SB.AppendLine(@"		public static string soPath = " + "\"" + string.Format(PathSettingSO.Ins.excelTableSOPath, info.tableName) + "\";");
			SB.AppendLine(@"		private static " + info.tableName + " ins;");
			SB.AppendLine(@"		public static " + info.tableName + " Ins");
			SB.AppendLine(@"		{");
			SB.AppendLine(@"			get");
			SB.AppendLine(@"			{");
			SB.AppendLine(@"				if (ins == null)");
			SB.AppendLine(@"				{");
			SB.AppendLine(@"					#if UNITY_EDITOR");
			SB.AppendLine(@"						ins = AssetDatabase.LoadAssetAtPath<" + info.tableName + ">(soPath);");
			SB.AppendLine(@"						if (ins == null)");
			SB.AppendLine(@"						{");
			SB.AppendLine(@"							ins = ScriptableObject.CreateInstance<" + info.tableName + ">();");
			SB.AppendLine(@"							AssetDatabase.CreateAsset(ins, soPath);");
			SB.AppendLine(@"							AssetDatabase.SaveAssets();");
			SB.AppendLine(@"							AssetDatabase.Refresh();");
			SB.AppendLine(@"						}");
			SB.AppendLine(@"					#endif");
			SB.AppendLine("");
			SB.AppendLine(@"					#if !UNITY_EDITOR");
			SB.AppendLine(@"						ins = AssetUtil.LoadAsset<" + info.tableName + ">(soPath);");
			SB.AppendLine(@"					#endif");
			SB.AppendLine(@"				}");
			SB.AppendLine(@"				return ins;");
			SB.AppendLine(@"			}");
			SB.AppendLine(@"		}");


			SB.AppendLine($"        public void AddNodeData(" + info.nodeName + " nodeData)");
			SB.AppendLine(@"		{");
			SB.AppendLine(@"			data.Add(nodeData);");
			if (info.keys.Count > 0)
			{
				SB.AppendLine(@"			excelDictionary.Add(nodeData, keys);");
			}
			SB.AppendLine(@"		}");


			SB.AppendLine($"        public void Clear()");
			SB.AppendLine(@"		{");
			SB.AppendLine(@"			data.Clear();");
			if (info.keys.Count > 0)
			{
				SB.AppendLine(@"			excelDictionary.Clear();");
			}
			SB.AppendLine(@"		}");


			if (info.keys.Count > 0)
			{
				SB.AppendLine(@"		public void SaveExcelDictionary()");
				SB.AppendLine(@"		{");
				SB.AppendLine(@"			excelDictionary.dic.SaveData();");
				SB.AppendLine(@"		}");

				//添加查找接口
				SB.AppendLine();
				for (int i = 0; i < info.keys.Count; i++)
				{
					string resString = info.nodeName;
					if (i != info.keys.Count - 1)
					{
						StringBuilder resSB = new StringBuilder();
						resSB.Append("ExcelDictionary<");
						for (int j = i + 1; j < info.keys.Count; j++)
						{
							resSB.Append($"{info.keyTypes[j]}, ");
						}
						resSB.Append($"{info.nodeName}>");
						resString = resSB.ToString();
					}
					SB.Append($"		public static {resString} Find(");
					for (int j = 0; j <= i; j++)
					{
						string splitStr = j != i ? ", " : "";
						SB.Append($"{info.keyTypes[j]} key{j + 1}{splitStr}");
					}
					SB.Append(")\n");
					SB.AppendLine("		{");
					SB.Append("			return Ins.excelDictionary.Find(");
					for (int j = 0; j <= i; j++)
					{
						string splitStr = j != i ? ", " : "";
						SB.Append($"key{j + 1}{splitStr}");
					}
					SB.Append(");\n");
					SB.AppendLine("		}");
				}
			}

			SB.AppendLine(@"	}");
			SB.AppendLine(@"}");
			return SB.ToString();
		}

		/// <summary>
		/// 根据Excel文件信息生成枚举脚本文件
		/// </summary>
		/// <param name="info"></param>
		/// <returns></returns>
		public static string GetExcelEnumText(ExcelTableInfo info)
		{
			StringBuilder SB = new StringBuilder();
			int nameIndex = 0, validIndex = 0;

			for (int i = 0; i < info.fieldNames.Length; i++)
			{
				if (info.fieldNames[i] == info.keys[0])
					nameIndex = i + info.ignoreCol;

				if (info.data[1][i].Contains("valid"))
					validIndex = i + info.ignoreCol;
			}


			for (int i = info.ignoreRow; i < info.row; i++)
			{
				SB.AppendLine($"//{info.data[i][0]}");
				SB.AppendLine($"public enum {info.data[i][nameIndex]}");
				SB.AppendLine("{");
				for (int j = info.ignoreCol + 1; j < info.col; j++)
				{
					if (j == nameIndex || j == validIndex) continue;

					if (string.IsNullOrEmpty(info.data[i][j]))
						break;
					string[] str = info.data[i][j].Split("#");
					if (str.Length == 1)
						SB.AppendLine($"	{info.data[i][j]},");
					else
					{
						SB.AppendLine($"	{str[0]},	//{str[1]}");
					}
				}
				SB.AppendLine("}");
				SB.AppendLine("");
			}
			return SB.ToString();
		}

		/// <summary>
		/// 获取面板Panel的模板类文本
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public static string GetTemplatePanelClassText(string name)
		{
			string addr = string.Format(PathSettingSO.Ins.panelPrefabPath, name);
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"using System.Collections;");
			SB.AppendLine(@"using System.Collections.Generic;");
			SB.AppendLine(@"using UnityEngine;");
			SB.AppendLine(@"using UnityEngine.UI;");
			SB.AppendLine(@"using TMPro;");
			SB.AppendLine(@"using Super;");
			SB.AppendLine();
			SB.AppendLine($"public class {name} : PanelBase");
			SB.AppendLine("{");
			SB.AppendLine();
			SB.AppendLine(@"	[HideInInspector]");
			SB.AppendLine($"	public static string addr = {"\"" + addr + "\""};");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnInit()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnOpen(params object[] args)");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnUpdateData()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnRefresh()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	#region 自定义函数");
			SB.AppendLine();
			SB.AppendLine(@"	#endregion");
			SB.AppendLine();
			SB.AppendLine(@"	#region 回调函数");
			SB.AppendLine();
			SB.AppendLine(@"	#endregion");
			SB.AppendLine("}");
			return SB.ToString();
		}

		/// <summary>
		/// 创建面板Widget的模板类文本
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		public static string GetTemplateWidgetClassText(string name)
		{
			string addr = string.Format(PathSettingSO.Ins.widgetPrefabPath, name);
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"using System.Collections;");
			SB.AppendLine(@"using System.Collections.Generic;");
			SB.AppendLine(@"using UnityEngine;");
			SB.AppendLine(@"using UnityEngine.UI;");
			SB.AppendLine(@"using TMPro;");
			SB.AppendLine(@"using Super;");
			SB.AppendLine();
			SB.AppendLine($"public class {name} : WidgetBase");
			SB.AppendLine("{");
			SB.AppendLine();
			SB.AppendLine(@"	[HideInInspector]");
			SB.AppendLine($"	public static string addr = {"\"" + addr + "\""};");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnInit()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnOpen(params object[] args)");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnUpdateData()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	public override void OnRefresh()");
			SB.AppendLine(@"	{");
			SB.AppendLine();
			SB.AppendLine(@"	}");
			SB.AppendLine();
			SB.AppendLine(@"	#region 自定义函数");
			SB.AppendLine();
			SB.AppendLine(@"	#endregion");
			SB.AppendLine();
			SB.AppendLine(@"	#region 回调函数");
			SB.AppendLine();
			SB.AppendLine(@"	#endregion");
			SB.AppendLine("}");
			return SB.ToString();
		}

		public static string GetCustomLangKeysTipText()
		{
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"# 1: #开头代表注释行");
			SB.AppendLine(@"# 2: 程序中需要适配多语言的文字、配置请在这添加key");
			SB.AppendLine(@"# 3: 换行使用\h代替系统原本的\n");
			return SB.ToString();
		}

		public static string GetExcelLangKeysTipText()
		{
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"# 1: #开头代表注释行");
			SB.AppendLine(@"# 2: 不需要手动添加，由框架工具自动生成");
			SB.AppendLine(@"# 3: 换行使用\h代替系统原本的\n");
			return SB.ToString();
		}

		public static string GetLangKeysTipText()
		{
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"# 1: #开头代表注释行");
			SB.AppendLine(@"# 2: 不需要手动添加，由框架工具自动生成");
			SB.AppendLine(@"# 3: 换行使用\h代替系统原本的\n");
			return SB.ToString();
		}

		public static string GetLangsTipText()
		{
			StringBuilder SB = new StringBuilder();
			SB.AppendLine(@"# 1: #开头代表注释行");
			SB.AppendLine(@"# 2: 每行内容相互独立");
			SB.AppendLine(@"# 3: 原文为key,翻译文本为value,中间用'='隔开");
			SB.AppendLine(@"# 4: key 和 翻译文本 前后的空格默认忽略");
			SB.AppendLine(@"# 5: 例如：原文：我的	==>翻译后==>	我的=my");

			return SB.ToString();
		}
	}
}
